/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package idv.cloudee.proxy2.impl.getpost;

import com.cirnoworks.http.utils.HTTPUtils;
import com.cirnoworks.http.utils.HeaderRequest;
import com.cirnoworks.http.utils.HeaderResponse;
import com.cirnoworks.http.utils.exception.BadRequestException;
import idv.cloudee.proxy2.framework.ProxySession;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

/**
 *
 * @author yuxuanhuang
 */
public class GETPOSTDealerOverProxy extends GETPOSTDealer {

    private String proxyAddress;
    private int proxyPort;

    public String getProxyAddress() {
        return proxyAddress;
    }

    public void setProxyAddress(String proxyAddress) {
        this.proxyAddress = proxyAddress;
    }
//    private final static ThreadLocal<Socket> proxyConn = new ThreadLocal<Socket>();

    public int getProxyPort() {
        return proxyPort;
    }

    public void setProxyPort(int proxyPort) {
        this.proxyPort = proxyPort;
    }

    public boolean dealRequest(HeaderRequest requestHeader, Socket conn, ProxySession session) throws BadRequestException {
        boolean keepAlive = true;
        Socket target = null;// = proxyConn.get();
        try {
            InputStream is = conn.getInputStream();
            OutputStream os = conn.getOutputStream();
            HTTPUtils.readHeader(is, requestHeader);
            for (GETPOSTModifier modifier : modifiers) {
                modifier.beginRequest(session);
            }

            for (GETPOSTModifier modifier : modifiers) {
                requestHeader = modifier.modifyRequest(requestHeader);
            }

            if (!"keep-alive".equals(requestHeader.getLastValue("Proxy-Connection"))) {
                keepAlive = false;
            }

            //= new Socket(proxyAddress, proxyPort);
            target = (Socket) session.get("ProxyConnection");
//            System.out.println(target + " " + (target == null ? "" : target.isClosed()));
            if (target == null || target.isClosed()) {
                target = new Socket(proxyAddress, proxyPort);
                session.put("ProxyConnection", target);
                //proxyConn.set(target);
            }
//            System.out.println(System.identityHashCode(Thread.currentThread()) + "  " + System.identityHashCode(target));
            OutputStream tos = target.getOutputStream();
            InputStream tis = target.getInputStream();
            tos.write(requestHeader.getRequestLine().getBytes(HTTPUtils.ISO8859_1));
            tos.write(HTTPUtils.CRLF);
            HTTPUtils.sendHead(tos, requestHeader);
            if (requestHeader.getMethod().equals("POST")) {
                OutputStream mos = tos;
                for (GETPOSTModifier modifier : modifiers) {
                    mos = modifier.getPOSTOutputStream(mos);
                }
                keepAlive &= HTTPUtils.deliveryEntity(requestHeader, is, mos, keepAlive);
            }
            HeaderResponse headerResponse = new HeaderResponse();
            HTTPUtils.readHeaderResponse(tis, headerResponse);

            for (GETPOSTModifier modifier : modifiers) {
                headerResponse = modifier.modifyResponse(headerResponse);
            }

            if (!"keep-alive".equals(headerResponse.getLastValue("Proxy-Connection"))) {
                keepAlive = false;
            }

            os.write(headerResponse.getResponseLine().getBytes(HTTPUtils.ISO8859_1));
            os.write(HTTPUtils.CRLF);


            HTTPUtils.sendHead(os, headerResponse);

            OutputStream mos = os;
            for (GETPOSTModifier modifier : modifiers) {
                mos = modifier.getResponseOutputStream(mos);
            }

            keepAlive &= HTTPUtils.deliveryEntity(headerResponse, tis, mos, keepAlive);
        } catch (IOException e) {
            e.printStackTrace();
            keepAlive = false;
        } catch (RuntimeException e) {
            e.printStackTrace();
            keepAlive = false;
        } finally {
            try {
                for (GETPOSTModifier modifier : modifiers) {
                    modifier.requestOver();
                }
            } catch (RuntimeException e) {
            }
            if (!keepAlive) {
                try {
                    target.close();
                } catch (IOException e) {
                } catch (RuntimeException e) {
                }
            }

        }
        if (!keepAlive) {
            session.remove("ProxyConnection");
//            proxyConn.remove();
        }
//        System.out.println(keepAlive);
        return keepAlive;
    }
}
